#include <FServer/MySQL/MySQLRequest.h>

#include <algorithm>

namespace keeper_server {

MySQLHandShake::MySQLHandShake() {
  proto_version = 10;
  server_version = SERVER_VERSION;
  thread_id = 2;
  memcpy(server_scramble, "12345678901234567890", SERVER_SCRAMBLE_LEN);
  server_scramble[SERVER_SCRAMBLE_LEN] = '\0';

  generate_user_salt(server_scramble, SERVER_SCRAMBLE_LEN + 1);
  //  capability_flags = CLIENT_BASIC_FLAGS | ~CLIENT_PLUGIN_AUTH;
  capability_flags = CLIENT_BASIC_FLAGS;
  capability_flags = capability_flags & ~CLIENT_SSL;
  character_set = SERVER_CHARSET;
  status_flags = SERVER_STATUS_AUTOCOMMIT;
  server_scramble_len = 0;
  auth_plugin_name = "mysql_native_password";
}

void MySQLHandShake::packBody(MySQLPacket *packet) {
  packet->packUInt8(proto_version);
  packet->packStr(server_version.c_str());
  packet->packUInt32(thread_id);
  packet->packStr(server_scramble, 8);
  packet->fill('\0', 1);
  packet->packUInt16(capability_flags);
  packet->packUInt8(character_set);
  packet->packUInt16(status_flags);
  packet->packUInt16(capability_flags >> 16);

  if (capability_flags & CLIENT_PLUGIN_AUTH) {
    packet->packUInt8(auth_plugin_name.length());
  } else {
    packet->packChar('\0');
  }
  packet->fill('\0', 10);

  if (capability_flags & CLIENT_SECURE_CONNECTION) {
    int len = server_scramble_len > SERVER_SCRAMBLE_LEN + 1
                  ? server_scramble_len - 8 + 1
                  : SERVER_SCRAMBLE_LEN - 8 + 1;
    LOG_INFO("len:%d, sencond scramble:%s", len, server_scramble + 8);
    packet->packStr(server_scramble + 8, len);
  }

  if (capability_flags & CLIENT_PLUGIN_AUTH) {
    packet->packStr(auth_plugin_name.c_str());
  }
}
MySQLHandShakeResponse::MySQLHandShakeResponse() {
  client_flag = 0;
  max_packet_size = 0;
  character_set = SERVER_CHARSET;
  memset(filter, '\0', FILTER_LENGTH);
  memset(client_scramble, '\0', SERVER_SCRAMBLE_LEN);
  user_name = "";
  database = "";
  client_auth_plugin = "";
}

void MySQLHandShakeResponse::packBody(MySQLPacket *packet) {}

void MySQLHandShakeResponse::unpackBody(MySQLPacket *packet) {
  packet->unpackUInt32(&client_flag);
  packet->unpackUInt32(&max_packet_size);
  packet->unpackUInt8(&character_set);
  packet->skip(FILTER_LENGTH);
  packet->unpackStr(user_name);
  if (client_flag & CLIENT_SECURE_CONNECTION) {
    UInt8 scramble_len;
    packet->unpackUInt8(&scramble_len);
    packet->unpackStr(client_scramble, scramble_len);
  } else {
    packet->unpackStr(client_scramble);
  }

  if (client_flag & CLIENT_CONNECT_WITH_DB) {
    packet->unpackStr(database);
  }
  if (client_flag & CLIENT_PLUGIN_AUTH) {
    packet->unpackStr(client_auth_plugin);
  }
}

void MySQLOKResponse::packBody(MySQLPacket *packet){
  packet->packChar('\0');
  packet->packLenencInt(affected_rows);
  packet->packLenencInt(last_insert_id);
  packet->packUInt16(status_flags);
  packet->packUInt16(warnings);
};

void MySQLEOFResponse::packBody(MySQLPacket *packet) {
  packet->packChar(0XFE);
  packet->packLenencInt(affected_rows);
  packet->packLenencInt(last_insert_id);
  packet->packUInt16(status_flags);
  packet->packUInt16(warnings);
};

}  // namespace keeper_server
